/*

 Copyright (C) 2009-2011 Oleksandr Natalenko aka post-factum

 This program is free software; you can redistribute it and/or modify
 it under the terms of the Universal Program License as published by
 Oleksandr Natalenko aka post-factum; see file COPYING for details.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 You should have received a copy of the Universal Program
 License along with this program; if not, write to
 pfactum@gmail.com

*/

package demodulation;

import helper.BinaryNumber;
import modulation.ModulatorController;

import java.util.ArrayList;
import java.util.List;

/**
 * Model of resolver device
 *
 * @author Oleksandr Natalenko aka post-factum
 */
public class Resolver {
    private List<DigitalSignal> summatorSignal;
    private List<Integer> lengthMap;
    private double threshold;
    private List<BinaryNumber> ethalonBinarySequence;
    private List<BinaryNumber> outputSequence = new ArrayList<BinaryNumber>();

    /**
     * Creates resolver
     *
     * @param _summatorSignal        signal from summator to operate on
     * @param _lengthMap
     * @param _threshold             threshold value to decide which symbol should be registered
     * @param _ethalonBinarySequence ethalon binary sequence to compare with
     */

    public Resolver(List<DigitalSignal> _summatorSignal, double _threshold, List<Integer> _lengthMap, List<BinaryNumber> _ethalonBinarySequence) {
        summatorSignal = _summatorSignal;
        threshold = _threshold;
        ethalonBinarySequence = _ethalonBinarySequence;
        lengthMap = _lengthMap;
    }

    /**
     * Runs resolving
     *
     * @return received bits
     */
    public List<BinaryNumber> getBinaryNumbers() {
        List<BinaryNumber> resolvedSequence = new ArrayList<BinaryNumber>();

        //use classic resolving algorithm if enabled
        //resolves input signal
        List<Boolean> resolvedLinearSequence = new ArrayList<Boolean>();
        for (DigitalSignal cds : summatorSignal) {
            double value = cds.getSample(cds.getSamplesCount() - 1).getY();
            resolvedLinearSequence.add(value > threshold);
        }
        //recombines linear sequence into blocks
        int index = 0;
        for (Integer ci : lengthMap) {
            boolean[] newBlock = new boolean[ci];
            for (int i = 0; i < ci; i++)
                newBlock[i] = resolvedLinearSequence.get(index + i);
            resolvedSequence.add(new BinaryNumber(newBlock));
            index += ci;
        }
        outputSequence = resolvedSequence;
        return outputSequence;
    }

}
